package com.xcity.game.peakroad;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xcity.db.entity.Player;
import com.xcity.game.combat.attr.CombatAttribute;
import com.xcity.game.common.Cause;
import com.xcity.game.common.MessageConst;
import com.xcity.game.event.GameEvents;
import com.xcity.game.item.ItemInfo;
import com.xcity.game.item.ItemService;
import com.xcity.game.item.drop.Drop;
import com.xcity.game.item.drop.DropGroup;
import com.xcity.game.item.drop.listener.MultiDropAdapter;
import com.xcity.game.peakroad.model.PeakRoadInstance;
import com.xcity.game.peakroad.template.PeakRoadTemplate;
import com.xcity.pomelo.PomeloRoute;
import com.xcity.pomelo.push.msg.BatchItemsPush;
import com.xcity.pomelo.request.PeakRoadFastPassRequest;
import com.xcity.pomelo.request.PeakRoadGetBuffRequest;
import com.xcity.pomelo.request.PeakRoadGetRewardRequest;
import com.xcity.pomelo.request.PeakRoadRequest;
import com.xcity.pomelo.response.HintResponse;
import com.xcity.pomelo.response.PeakRoadFastPassResponse;
import com.xcity.pomelo.response.PeakRoadFastPassResponse.FloorReward;
import com.xcity.pomelo.response.PeakRoadGetBuffResponse;
import com.xcity.pomelo.response.PeakRoadGetRewardResponse;
import com.xcity.pomelo.response.PeakRoadResponse;

import naga.x.App;
import naga.x.event.Event;
import naga.x.event.EventListener;
import naga.x.game.template.TemplateService;
import naga.x.net.Session;
import naga.x.net.annotation.OPHandler;
import naga.x.net.impl.pomelo.annotation.PomeloOP;
import naga.x.service.Service;
import naga.x.service.ServiceException;
import naga.x.util.CommonUtils;

/**
 * 巅峰之路（副本）
 * @author yang.li
 *
 */
@OPHandler
public class PeakRoadService implements Service, EventListener {

	protected List<PeakRoadTemplate> templates; // 所有楼层信息
	
	protected static final Logger LOG = LoggerFactory.getLogger(PeakRoadService.class);
	
	@Override
	public void startup() throws ServiceException {
		templates = App.getApp().getServiceManager().get(TemplateService.class).getTemplatesList(PeakRoadTemplate.class);
		App.getApp().getEventManager().register(this);
	}

	@Override
	public void shutdown() throws ServiceException {
	}

	@Override
	public String getId() {
		return getClass().getName();
	}
	
	@Override
	public int[] getEventTypes() {
		return new int[] { GameEvents.EVENT_PLAYER_LOADED };
	}

	@Override
	public void handleEvent(Event event) {
		Player player = event.getParameter();
		player.getPeakRoadInstance().init();
	}
	
	public List<PeakRoadTemplate> getTemplates() {
		return templates;
	}
	
	@PomeloOP(PomeloRoute.INSTANCE_PEAK_ROAD_INFO)
	protected void requestInfo(Session session, PeakRoadRequest req) {
		Player player = session.getClient();

		PeakRoadInstance instance = player.getPeakRoadInstance();
		int fpFloor = instance.getFloor();
		if(fpFloor >= PeakRoadUtils.getTopFloor()){
			if(fpFloor == PeakRoadUtils.getTopFloor() && instance.hasState(PeakRoadInstance.STATE_REWARD_ITEM_MASK)){
				boolean curDoneState = instance.hasState(PeakRoadInstance.STATE_PREVIOUS_CHALLENGE_MASK);
				instance.fireChallengeFailed(null);
				if(!curDoneState){
					instance.setJoinedTimes(instance.getJoinedTimes() + 1);
				}
			}
		}
		session.send(new PeakRoadResponse(req.getSerial(), player, req.getFloor(), req.getCount()));
	}
	
	@PomeloOP(PomeloRoute.INSTANCE_PEAK_ROAD_GET_BUFF)
	protected void requestGetBuff(Session session, PeakRoadGetBuffRequest req) {
		Player player = session.getClient();
		PeakRoadInstance instance = player.getPeakRoadInstance();
		if (instance.hasState(PeakRoadInstance.STATE_REWARD_BUFF_MASK)) {
			session.send(new HintResponse(req.getSerial(), MessageConst.INSTANCE_PEAK_ROAD_BUFF_GAINED));
			return;
		}
		if (!instance.hasState(PeakRoadInstance.STATE_CHALLENGE_MASK)) {
			session.send(new HintResponse(req.getSerial(), MessageConst.INSTANCE_PEAK_ROAD_REWARD_MUST_PASS));
			return;
		}
		PeakRoadTemplate template = PeakRoadUtils.getTemplate(instance.getFloor());
		if (template == null || template.getType() != PeakRoadTemplate.FLOOR_REWARD) {
			session.send(new HintResponse(req.getSerial(), MessageConst.INSTANCE_PEAK_ROAD_REWARD_MUST_PASS));
			return;
		}
		int buffId = req.getBuff();
		CombatAttribute buff = template.getBuff(buffId);
		if (buff == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.INSTANCE_PEAK_ROAD_HAVE_NO_BUFF));
			return;
		}
		instance.addBuff(buff, true);
		session.send(new PeakRoadGetBuffResponse(req.getSerial(), buffId, buff));
		LOG.info("[PEAKROAD BUFF]ID[{}]FLOOR[{}]BUFF[{}={}]", player.getId(), template.getId(), buff.getType(), buff.getValue());
	}
	
	@PomeloOP(PomeloRoute.INSTANCE_PEAK_ROAD_GET_REWARD)
	protected void requestGetReward(Session session, PeakRoadGetRewardRequest req) {
		Player player = session.getClient();
		PeakRoadInstance instance = player.getPeakRoadInstance();
		if (instance.hasState(PeakRoadInstance.STATE_REWARD_ITEM_MASK)) {
			session.send(new HintResponse(req.getSerial(), MessageConst.REWARD_ALREADY_RECEIVED));
			return;
		}
		if (!instance.hasState(PeakRoadInstance.STATE_CHALLENGE_MASK)) {
			session.send(new HintResponse(req.getSerial(), MessageConst.INSTANCE_PEAK_ROAD_REWARD_MUST_PASS));
			return;
		}
		if (!instance.hasState(PeakRoadInstance.STATE_REWARD_BUFF_MASK)) {
			session.send(new HintResponse(req.getSerial(), MessageConst.INSTANCE_PEAK_ROAD_REWARD_MUST_AFTER_BUFF));
			return;
		}
		PeakRoadTemplate template = PeakRoadUtils.getTemplate(instance.getFloor());
		if (template == null || template.getType() != PeakRoadTemplate.FLOOR_REWARD) {
			session.send(new HintResponse(req.getSerial(), MessageConst.INSTANCE_PEAK_ROAD_REWARD_MUST_PASS));
			return;
		}
		DropGroup drop = template.getDropGroup(instance.getLastChallengeDiff());
		if (drop == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.HAVE_NO_REWARD));
			return;
		}
		instance.addState(PeakRoadInstance.STATE_REWARD_ITEM_MASK);
		PeakRoadTemplate next = null;
		if (instance.moveToNext()) {
			next = PeakRoadUtils.getTemplate(instance.getFloor());
		}
		BatchItemsPush push = new BatchItemsPush();
		drop.drop(Drop.RND, player, Cause.PEAK_ROAD, new MultiDropAdapter() {
			@Override
			public void itemDroped(Player player, int itemId, int count) {
				push.add(itemId, count);
			}
			@Override
			public void expDroped(Player player, int val) {
			}
			@Override
			public void goldDroped(Player player, int gold) {
				push.addGold(gold);
			}
			@Override
			public void stoneDroped(Player player, int stone) {
				push.addStone(stone);
			}
		});
		int fpFloor = instance.getFloor();
		if(fpFloor >= PeakRoadUtils.getTopFloor()){
			boolean curDoneState = instance.hasState(PeakRoadInstance.STATE_PREVIOUS_CHALLENGE_MASK);
			instance.fireChallengeFailed(null);
			if(!curDoneState){
				instance.setJoinedTimes(instance.getJoinedTimes() + 1);
				next = PeakRoadUtils.getTemplate(instance.getFloor());
			}
		}
		session.send(new PeakRoadGetRewardResponse(req.getSerial(), player, req.getIndex(), next));
		session.send(push);

		LOG.info("[PEAKROAD REWARD]ID[{}]FLOOR[{}]NEXT[{}]", player.getId(), template.getId(), next != null ? next.getId() : template.getId());
	}
	
	@PomeloOP(PomeloRoute.INSTANCE_PEAK_ROAD_FAST_PASS)
	protected void requestFastPass(Session session, PeakRoadFastPassRequest req) {
		Player player = session.getClient();
		PeakRoadInstance instance = player.getPeakRoadInstance();
		if (instance.getFloor() >= instance.getPassedMaxHardFloor()) {
			session.send(new HintResponse(req.getSerial(), MessageConst.ILLEGAL_OPERATION));
			return;
		}
		if (!instance.hasState(PeakRoadInstance.STATE_PREVIOUS_CHALLENGE_MASK) && PeakRoadUtils.getLeftTimes(player) <= 0) {
			session.send(new HintResponse(req.getSerial(), MessageConst.INSTANCE_PEAK_ROAD_JOINED_TIMES_MAXED));
			return;
		}

		// 结算每层奖励（物品、巅峰币、buff）
		List<FloorReward> rewards = new ArrayList<FloorReward>(instance.getPassedMaxHardFloor() - instance.getFloor() + 1);
		for (int i = instance.getFloor(); i <= instance.getPassedMaxHardFloor(); i++) {
			PeakRoadTemplate template = PeakRoadUtils.getTemplate(i);
			// 巅峰币
			if (template.getPeakCoin() > 0) {
				player.addPeakCoin(template.getPeakCoin(), Cause.PEAK_ROAD_FAST_PASS);
			}
			// 物品掉落
			Map<Integer, ItemInfo> itemsMapping = new LinkedHashMap<Integer, ItemInfo>();
			DropGroup drop = template.getDropGroup(PeakRoadTemplate.DIFF_HARD);
			if (drop != null) {
				drop.drop(Drop.RND, player, Cause.PEAK_ROAD_FAST_PASS, new MultiDropAdapter() {
					@Override
					public void goldDroped(Player player, int gold) {
						itemDroped(player, ItemService.goldDefault.getId(), gold);
					}
					@Override
					public void stoneDroped(Player player, int stone) {
						itemDroped(player, ItemService.stoneDefault.getId(), stone);
					}
					@Override
					public void itemDroped(Player player, int itemId, int count) {
						ItemInfo item = itemsMapping.get(itemId);
						if (item == null) {
							item = new ItemInfo(itemId, 0);
							itemsMapping.put(itemId, item);
						}
						item.setCount(item.getCount() + count);
					}
				});
			}
			// buff
			CombatAttribute[] buffArr = template.getWrappedBuffs();
			CombatAttribute buff = null;
			if (buffArr != null && buffArr.length > 0
					&& !instance.hasState(PeakRoadInstance.STATE_REWARD_BUFF_MASK)/*玩家处于奖励层时有可能已领取过buff*/) {
				int index = CommonUtils.randomInt(buffArr.length);
				buff = buffArr[index];
				instance.addBuff(buff, true);
			}
			
			instance.removeState(PeakRoadInstance.STATE_REWARD_BUFF_MASK);
			instance.removeState(PeakRoadInstance.STATE_REWARD_ITEM_MASK);
			
			FloorReward fr = new FloorReward(i, itemsMapping.values(), buff != null ? Arrays.asList(buff) : null, template.getPeakCoin());
			rewards.add(fr);
		}
		instance.fastPass();
		
		App.getApp().getEventManager().addEvent(GameEvents.EVENT_PEAK_ROAD_WIN, player);
		int fpFloor = instance.getFloor();
		if(fpFloor >= PeakRoadUtils.getTopFloor()){
			boolean curDoneState = instance.hasState(PeakRoadInstance.STATE_PREVIOUS_CHALLENGE_MASK);
			instance.fireChallengeFailed(null);
			if(!curDoneState){
				instance.setJoinedTimes(instance.getJoinedTimes() + 1);
			}
		}
		
//		PeakRoadTemplate current = PeakRoadUtils.getTemplate(instance.getFloor());
		session.send(new PeakRoadFastPassResponse(req.getSerial(), rewards, instance.getFloor()));
		LOG.info("[PEAKROAD FASTPASS]ID[{}]FLOOR[{}]PASSEDMAX[{}]", player.getId(), fpFloor, instance.getPassedMaxHardFloor());
	}
	
//	@PomeloOP(PomeloRoute.INSTANCE_PEAK_ROAD_FAST_PASS)
//	protected void requestFastPass(Session session, PeakRoadFastPassRequest req) {
//		Player player = session.getClient();
//		PeakRoadInstance instance = player.getPeakRoadInstance();
//		if (!instance.hasState(PeakRoadInstance.STATE_PREVIOUS_CHALLENGE_MASK) && PeakRoadUtils.getLeftTimes(player) <= 0) {
//			session.send(new HintResponse(req.getSerial(), MessageConst.INSTANCE_PEAK_ROAD_JOINED_TIMES_MAXED));
//			return;
//		}
//		if (instance.getFloor() != 1 || instance.getLastMaxFloor() <= instance.getFloor()) {
//			session.send(new HintResponse(req.getSerial(), MessageConst.ILLEGAL_OPERATION));
//			return;
//		}
//
//		int lastMaxFloor = instance.getLastMaxFloor();
//		if (PeakRoadUtils.getTemplate(lastMaxFloor).getType() == PeakRoadTemplate.FLOOR_CHALLENGE) {
//			// 最后一层为挑战层，则不结算最后一层奖励
//			--lastMaxFloor;
//		}
//		// 结算buff
//		List<CombatAttribute> buffs = instance.getBuffs();
//		if (buffs == null) { // impossible
//			buffs = Collections.emptyList();
//		}
//		for (int i = 0; i < buffs.size(); i++) {
//			instance.addBuff(buffs.get(i), false);
//		}
//		// 结算每层奖励
//		final Map<Integer, ItemInfo> itemsMapping = new LinkedHashMap<Integer, ItemInfo>();
//		for (int i = instance.getFloor(); i <= instance.getLastMaxFloor(); i++) {
//			PeakRoadTemplate template = PeakRoadUtils.getTemplate(i);
//			if (template.getPeakCoin() > 0) {
//				player.addPeakCoin(template.getPeakCoin(), Cause.PEAK_ROAD_FAST_PASS);
//			}
//			DropGroup drop = template.getDropGroup(0);
//			if (drop != null) {
//				drop.drop(Drop.RND, player, Cause.PEAK_ROAD_FAST_PASS, new ItemDropListener() {
//					@Override
//					public void itemDroped(Player player, int itemId, int count) {
//						ItemInfo item = itemsMapping.get(itemId);
//						if (item == null) {
//							item = new ItemResponse(itemId, 0);
//							itemsMapping.put(itemId, item);
//						}
//						item.setCount(item.getCount() + count);
//					}
//				});
//			}
//		}
//		instance.fastPass();
//		
//		PeakRoadTemplate current = PeakRoadUtils.getTemplate(instance.getFloor());
//		session.send(new PeakRoadFastPassResponse(req.getSerial(), player, itemsMapping.values(), buffs, current));
//		LOG.info("[PEAKROAD FASTPASS]ID[{}]FLOOR[{}]", player.getId(), instance.getFloor());
//	}

	
}
